package com.tinysand.advert.mysql.listener.impl;

import com.github.shyiko.mysql.binlog.event.EventType;
import com.tinysand.advert.mysql.constant.Constant;
import com.tinysand.advert.mysql.constant.OperationType;
import com.tinysand.advert.mysql.dto.BinlogRowData;
import com.tinysand.advert.mysql.dto.MySqlRowData;
import com.tinysand.advert.mysql.dto.TableTemplate;
import com.tinysand.advert.mysql.listener.Listener;
import com.tinysand.advert.sender.Sender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author TINY
 */
@Slf4j
@Component
public class IncrementListener implements Listener {

    private final AggregationListener aggregationListener;

    @Resource(name = "indexSender")
    private Sender sender;

    public IncrementListener(AggregationListener aggregationListener) {
        this.aggregationListener = aggregationListener;
    }

    @Override
    @PostConstruct
    public void register() {
        log.info("开始注册表信息");
        Constant.table2Db.forEach((k, v) ->
                aggregationListener.register(v, k, this));
    }

    @Override
    public void onEvent(BinlogRowData eventData) {
        TableTemplate table = eventData.getTable();
        EventType eventType = eventData.getEventType();

        // 包装数据
        MySqlRowData rowData = new MySqlRowData();
        rowData.setTableName(table.getTableName());
        rowData.setLevel(eventData.getTable().getLevel());
        OperationType operationType = OperationType.convert(eventType);
        rowData.setOperationType(operationType);

        // 取出模板操作中对应的字段列表
        List<String> fieldList = table.getOpTypeFieldMap().get(
                operationType);
        if (null == fieldList) { return; }

        for (Map<String, String> afterMap : eventData.getAfter()) {
            Map<String, String> _afterMap = new HashMap<>();
            for (Map.Entry<String, String> entry : afterMap.entrySet()) {
                String colName = entry.getKey();
                String colValue = entry.getValue();

                _afterMap.put(colName, colValue);
            }
            rowData.getFieldValueMap().add(_afterMap);
        }
        sender.send(rowData);
    }
}
